package com.chang.member.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chang.common.utils.PageUtils;
import com.chang.common.utils.Query;
import com.chang.member.entity.MemberEntity;
import com.chang.member.entity.MemberLevelEntity;
import com.chang.member.mapper.MemberDao;
import com.chang.member.mapper.MemberLevelDao;
import com.chang.member.service.MemberService;
import com.chang.member.vo.GiteeAccountVo;
import com.chang.member.vo.MemberLoginVo;
import com.chang.member.vo.MemberRegisterVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Map;

@Slf4j
@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Resource
    MemberLevelDao memberLevelDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(new Query<MemberEntity>().getPage(params), new QueryWrapper<>());

        return new PageUtils(page);
    }

    @Override
    public Boolean register(MemberRegisterVo memberRegister) {

        MemberEntity member = new MemberEntity();
        MemberLevelEntity memberLevel = memberLevelDao.getDefaultLevel();
        member.setLevelId(memberLevel.getId());
        member.setUsername(memberRegister.getUserName());
        member.setEmail(memberRegister.getEmail());
        member.setNickname(memberRegister.getUserName());
        // 数据库中的密码不能明文存储 需要加密 这里用的spring security自带的加密方法,每次加密后结果都不一样,验证的时候调用BCryptPasswordEncoder.matches方法返回鉴定结果
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        // 保存加密之后的密码
        member.setPassword(passwordEncoder.encode(memberRegister.getPassword()));
        return this.save(member);
    }

    @Override
    public Boolean checkEmailUnique(String email) {
        return this.exists(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getEmail, email));
    }

    @Override
    public Boolean checkUsernameUnique(String username) {
        return this.exists(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getEmail, username));
    }

    @Override
    public MemberEntity login(MemberLoginVo loginVo) {
        // 可以用用户名登录也可以用邮箱登录
        MemberEntity member = getOne(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getUsername, loginVo.getLoginacct()).or().eq(MemberEntity::getEmail, loginVo.getLoginacct()));
        if (member != null) {
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            boolean matches = passwordEncoder.matches(loginVo.getPassword(), member.getPassword());
            if (matches) {
                log.info("登录成功=>{}", member);
                return member;
            }
            log.info("登录失败,用户密码错误");
        }
        log.info("登录失败,不存在该用户");
        return null;
    }


    /**
     * @param: [giteeAccountVo]
     * @return: com.chang.member.entity.MemberEntity
     * @author changzhenxi
     * @date 2024/12/5 - 15:41
     * @history 2024/12/5 - 15:41 changzhenxi create  登社交账号需要登录和注册两个逻辑合并
     * 另外这里我想过直接使用saveOrUpdate(),但是每次登录不管是否存在账号都往数据库传那么多数据不合适,就放弃了
     *       TODO 这里我感觉应该将第三方令牌直接放到redis中,减缓数据库压力
     */
    @Override
    public MemberEntity login(GiteeAccountVo giteeAccountVo) {

        long gitee_id = giteeAccountVo.getId();
        // 判断当前社交账号是否已经注册过 如果已经注册过则只需要更新第三方令牌和新令牌的过期时间即可
        MemberEntity member = getOne(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getGitee_uid, gitee_id));
        if (member != null) {
            member.setAccess_token(giteeAccountVo.getAccess_token());
            member.setExpires_in(Long.valueOf(giteeAccountVo.getExpires_in()));
            log.info("第三方账号已存在member = >{}", member);
            updateById(member);
            return member;
        } else {
            MemberEntity giteeMember = new MemberEntity();
            giteeMember.setGitee_uid(String.valueOf(gitee_id));
            giteeMember.setAccess_token(giteeAccountVo.getAccess_token());
            giteeMember.setExpires_in(Long.valueOf(giteeAccountVo.getExpires_in()));
            giteeMember.setHeader(giteeAccountVo.getAvatar_url());
            giteeMember.setSign(giteeAccountVo.getBio());
            giteeMember.setUsername(giteeAccountVo.getLogin());
            giteeMember.setEmail(giteeAccountVo.getEmail());
            giteeMember.setNickname(giteeAccountVo.getName());
            log.info("创建第三方账号giteeMember = >{}", giteeMember);
            save(giteeMember);
            return giteeMember;
        }
    }

}